﻿//
// Created by Administrator on 2025/7/2.
//
/*
 * 参考文献:
 * https://cplusplus.blog.csdn.net/article/details/115891320
 * */
#include <iostream>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace std;
using namespace cv;

// 延迟时间和最大卷积核尺寸
int DELAY_CAPTION = 1500;
int DELAY_BLUR = 100;
int MAX_KERNEL_LENGTH = 31;

// 原图与处理后的图像
Mat src;
Mat dst;

// 窗口名称
char window_name[] = "Smoothing Demo";

// 显示文字标题函数声明
int display_caption(const char* caption);
// 显示图像函数声明
int display_dst(int delay);

int main() {
    // 手动设置图像路径
    string img_path = "D:/demo6.jpg";

    // 读取彩色图像
    src = imread(img_path, IMREAD_COLOR);

    // 如果图像加载失败则报错退出
    if (src.empty()) {
        printf("❌ 图像读取失败，请检查路径: %s\n", img_path.c_str());
        return EXIT_FAILURE;
    }

    // 图像尺寸过大时自动缩小（保证宽或高不超过500）
    while (src.cols > 500 || src.rows > 500) {
        resize(src, src, Size(src.cols / 2, src.rows / 2));  // 每次缩小一半
    }

    // 创建显示窗口
    namedWindow(window_name, WINDOW_AUTOSIZE);

    // 显示原始图像标题
    if (display_caption("Original Image") != 0)
        return 0;

    // 显示原始图像
    dst = src.clone();
    if (display_dst(DELAY_CAPTION) != 0)
        return 0;

    // 显示均值滤波标题
    if (display_caption("Homogeneous Blur") != 0)
        return 0;

    // 应用不同尺寸的均值滤波
    for (int i = 1; i < MAX_KERNEL_LENGTH; i += 2) {
        blur(src, dst, Size(i, i), Point(-1, -1));  // 均值滤波
        if (display_dst(DELAY_BLUR) != 0)
            return 0;
    }

    // 显示高斯滤波标题
    if (display_caption("Gaussian Blur") != 0)
        return 0;

    // 应用不同尺寸的高斯滤波
    for (int i = 1; i < MAX_KERNEL_LENGTH; i += 2) {
        GaussianBlur(src, dst, Size(i, i), 0, 0);  // 高斯滤波
        if (display_dst(DELAY_BLUR) != 0)
            return 0;
    }

    // 显示中值滤波标题
    if (display_caption("Median Blur") != 0)
        return 0;

    // 应用不同尺寸的中值滤波
    for (int i = 1; i < MAX_KERNEL_LENGTH; i += 2) {
        medianBlur(src, dst, i);  // 中值滤波
        if (display_dst(DELAY_BLUR) != 0)
            return 0;
    }

    // 显示双边滤波标题
    if (display_caption("Bilateral Blur") != 0)
        return 0;

    // 应用不同尺寸的双边滤波
    for (int i = 1; i < MAX_KERNEL_LENGTH; i += 2) {
        bilateralFilter(src, dst, i, i * 2, i / 2);  // 双边滤波
        if (display_dst(DELAY_BLUR) != 0)
            return 0;
    }

    // 最后显示 "Done!" 提示
    display_caption("Done!");

    return 0;
}

// 显示指定标题文本（放在图像中心）
int display_caption(const char* caption) {
    dst = Mat::zeros(src.size(), src.type());  // 创建空黑图
    putText(dst, caption,
            Point(src.cols / 4, src.rows / 2),  // 设置文本位置
            FONT_HERSHEY_COMPLEX, 1,            // 字体样式和大小
            Scalar(255, 255, 255));             // 白色文字
    return display_dst(DELAY_CAPTION);
}

// 显示当前图像并等待指定毫秒时间
int display_dst(int delay) {
    imshow(window_name, dst);        // 显示图像
    int c = waitKey(delay);          // 等待按键
    if (c >= 0)
        return -1;                   // 如果有按键，返回中断
    return 0;
}
